using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;

namespace CNGraphi.U6URP
{
    /// <summary>
    /// 高斯模糊
    /// <para>作者：CN.Graphi</para>
    /// </summary>
    [VolumeComponentMenu("G Post-processing/Blur/Guassian")]
    public class GausBlur : GPostProcess
    {
        #region 参数
        public ClampedIntParameter Downsample = new ClampedIntParameter(2, 1, 10, true);
        public MinIntParameter Iteration = new MinIntParameter(2, 2, true);
        public ClampedFloatParameter Intensity = new ClampedFloatParameter(0.1f, 0.001f, 0.1f, true);
        #endregion


        public override bool IsActive() => mMaterial != null && Intensity.value != Intensity.max;


        TextureHandle temp0;
        TextureHandle temp1;


        internal override void OnTextureCreate(RenderGraph renderGraph, ContextContainer frameData)
        {
            UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
            var desc = cameraData.cameraTargetDescriptor;

            int downValue = Downsample.value;
            int tw = Mathf.Max(1, desc.width >> downValue);
            int th = Mathf.Max(1, desc.height >> downValue);

            desc.width = tw;
            desc.height = th;
            desc.depthBufferBits = 0;

            temp0 = UniversalRenderer.CreateRenderGraphTexture(renderGraph, desc, "GuasBlur_Temp0", false, FilterMode.Bilinear, TextureWrapMode.Clamp);
            temp1 = UniversalRenderer.CreateRenderGraphTexture(renderGraph, desc, "GuasBlur_Temp1", false, FilterMode.Bilinear, TextureWrapMode.Clamp);
        }

        internal override void OnTextureUseCommit(IUnsafeRenderGraphBuilder builder)
        {
            builder.UseTexture(temp0);
            builder.UseTexture(temp1);
        }

        internal override void OnRender(CommandBuffer cmd, PostProcessPassData passData, TextureHandle src, TextureHandle dst)
        {
            Draw(cmd, src, temp0);

            float blur = Intensity.value;
            for (int i = 0; i < Iteration.value; i++)
            {
                //x
                mMaterial.SetFloat("_Blur", blur * (i + 1));
                Draw(cmd, temp0, temp1, 0);
                CoreUtils.Swap(ref temp0, ref temp1);

                //y
                mMaterial.SetFloat("_Blur", blur * (i + 1));
                Draw(cmd, temp0, temp1, 1);
                CoreUtils.Swap(ref temp0, ref temp1);
            }

            Draw(cmd, temp0, dst);
        }


        protected override void OnDispose()
        {
        }

    }
}